package com.xishu.service;

import com.xishu.bo.LineUpCodeResponse;
import com.xishu.entity.shop.LineUp;
import com.xishu.entity.shop.LineUpConfig;
import com.xishu.entity.shop.Shop;
import com.xishu.exception.ResponseStatusException;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.util.CollectionUtil;
import com.xishu.util.DateUtil;
import com.xishu.util.Tools;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class LineUpService implements Tools {
    private static LineUpService instance = new LineUpService();
    private CommonService commonService = CommonService.getInstance();

    private LineUpService() {
    }

    public static LineUpService getInstance() {
        return instance;
    }

    /**
     * 获取餐厅最大的排队号
     *
     * @param shopId
     * @return
     */
    public int getMaxSerial(Long shopId, String code) {
        LineUp lineUp = new LineUp();
        lineUp.setShopId(shopId);
        lineUp.setCode(code);
        List<LineUp> lineUps = CommonService.getInstance().searchAll(lineUp);

        if (isEmpty(lineUps)) {
            return 0;
        }

        Optional<Integer> max = lineUps.stream().map(p -> p.getSerial()).max(Integer::compareTo);

        if (max.isPresent()) {
            return max.get();
        }

        return 0;
    }

    /**
     * 查询某一个排队情况
     *
     * @param shopId
     * @param code
     * @return
     */
    public List<LineUp> getLineUpList(Long shopId, String code) {
        LineUp lineUp = new LineUp();
        lineUp.setShopId(shopId);
        lineUp.setCode(code);
        lineUp.setLining(true);
        return commonService.searchAll(lineUp);
    }

    /**
     * 获取所队列的第一个号码
     *
     * @param shopId
     * @param code
     * @return
     */
    public LineUp getFirstLineUp(Long shopId, String code) {
        List<LineUp> lineUpList = getLineUpList(shopId, code);

        if (isNotEmpty(lineUpList)) {
            return lineUpList.get(0);
        }

        return null;
    }

    /**
     * 获取当前叫号
     *
     * @param shop
     * @param code
     * @return
     */
    public LineUp getCurrentLineUp(Shop shop, String code) {
        LineUp lineUp = new LineUp();
        lineUp.setShopId(shop.getId());
        lineUp.setStartCreateTime(shop.getOpenTime());
        lineUp.setCode(code);
        lineUp.setLining(false);
        lineUp.setPageSize(5);
        List<LineUp> lineUpList = commonService.findLimit(lineUp, 1);

        if (isNotEmpty(lineUpList)) {
            return lineUpList.get(0);
        }

        LineUp currentLineUp = new LineUp();
        currentLineUp.setCode(code);
        return currentLineUp;
    }

    /**
     * 通过电话号码来查询
     *
     * @param shopId
     * @param phone
     * @return
     */
    public List<LineUp> findLineUpListByPhone(Long shopId, String phone) {
        LineUp lineUp = new LineUp();
        lineUp.setShopId(shopId);
        lineUp.setPhone(phone);
        lineUp.setStartCreateTime(System.currentTimeMillis() - DateUtil.ONE_DAY);
        return commonService.searchAll(lineUp);
    }

    /**
     * 通过人数去找适合的编码
     *
     * @param personNumber
     * @return
     */
    public String getCode(int personNumber, Long shopId) throws ResponseStatusException {
        LineUpConfig lineUpConfig = new LineUpConfig();
        lineUpConfig.setShopId(shopId);
        List<LineUpConfig> lineUpConfigs = CommonService.getInstance().searchAll(lineUpConfig);

        VerifyUtil.verify(() -> isNotEmpty(lineUpConfigs), ResponseStatus.NOT_CONFIG_LINE_UP);


        Optional<Integer> min = lineUpConfigs.stream().filter(p -> getInt(p.getMaxLinePersons()) >= personNumber).map(p -> getInt(p.getMaxLinePersons())).min(Integer::compareTo);
        Optional<Integer> maxPersonsOptional = lineUpConfigs.stream().map(p -> getInt(p.getMaxLinePersons())).max(Integer::compareTo);

        VerifyUtil.verify(() -> min.isPresent(), ResponseStatus.NOT_MATCH_LINE_UP_CONFIG, maxPersonsOptional.get());

        LineUpConfig findLineUp = lineUpConfigs.stream().filter(p -> p.getMaxLinePersons() == min.get()).findFirst().get();
        VerifyUtil.verify(() -> isNotEmpty(findLineUp.getCode()), ResponseStatus.NOT_CONFIG_LINE_UP);
        return findLineUp.getCode();
    }

    /**
     * @param shopId
     */
    public void closeAllLineUp(Long shopId) throws Exception {
        LineUp lineUp = new LineUp();
        lineUp.setShopId(shopId);
        lineUp.setFlagDelete(false);
        lineUp.setBeRequest(true);
        commonService.delete(lineUp);
    }

    /**
     * 通过商铺以及唯一码查询配置
     *
     * @param shopId
     * @param code
     * @return
     */
    public LineUpConfig queryLineUpConfig(Long shopId, String code) throws Exception {
        VerifyUtil.verify(() -> shopId != null && code != null);
        LineUpConfig lineUpConfig = new LineUpConfig();
        lineUpConfig.setShopId(shopId);
        lineUpConfig.setCode(code);
        lineUpConfig.setEntity(true);
        return commonService.searchOne(lineUpConfig);
    }

    /**
     * 查询所有的排队配置
     *
     * @param shopId
     * @return
     */
    public List<LineUpConfig> queryAllLineUpConfig(Long shopId) throws ResponseStatusException {
        VerifyUtil.verify(() -> shopId != null);
        LineUpConfig lineUpConfig = new LineUpConfig();
        lineUpConfig.setShopId(shopId);
        lineUpConfig.setEntity(true);
        return commonService.searchAll(lineUpConfig);
    }

    /**
     * 查询所有队列里面的第一个排队
     *
     * @param shopId
     * @return
     */
    public List<LineUp> getAllCurrentLine(Long shopId) throws Exception {
        LineUpConfig reqLineUpConfig = new LineUpConfig();
        Shop shop = ShopService.getInstance().findShopById(shopId);
        reqLineUpConfig.setShopId(shopId);
        List<LineUpConfig> lineUpConfigs = commonService.searchAll(reqLineUpConfig);
        return lineUpConfigs.stream().map(lineUpConfig -> {
            LineUp currentLineUp = getCurrentLineUp(shop, lineUpConfig.getCode());
            return currentLineUp;
        }).collect(Collectors.toList());
    }

    public LineUpCodeResponse generateLineupCodeResponse(LineUp lineUp) {
        lineUp.setLining(true);
        List<LineUp> lineUpList = commonService.searchAll(lineUp);

        if (isEmpty(lineUpList)) {
            return null;
        }

        LineUp firstOne = lineUpList.get(0);
        LineUp lastOne = lineUpList.get(lineUpList.size() - 1);
        LineUpCodeResponse lineUpCodeResponse = new LineUpCodeResponse();
        lineUpCodeResponse.setFirstOne(firstOne.getCode() + firstOne.getSerial());
        lineUpCodeResponse.setWaitingSize(lineUpList.size() - 1);
        lineUpCodeResponse.setLastOne(lastOne.getCode() + lastOne.getSerial());
        lineUpCodeResponse.setCurrentId(firstOne.getId());

        //如果队列大于1，那么存在下一个叫号
        if (lineUpList.size() > 1) {
            LineUp nextOne = lineUpList.get(1);
            lineUpCodeResponse.setNextOne(nextOne.getCode() + nextOne.getSerial());
        }

        return lineUpCodeResponse;
    }
}
